package com.tanhua.server.service;

import com.tanhua.domain.db.UserInfo;
import com.tanhua.domain.mongo.Comment;
import com.tanhua.domain.vo.CommentVo;
import com.tanhua.domain.vo.PageResult;
import com.tanhua.dubbo.api.UserInfoApi;
import com.tanhua.dubbo.api.mongo.CommentApi;
import com.tanhua.server.interceptors.UserHolder;
import com.tanhua.server.utils.RelativeDateFormat;
import org.apache.dubbo.config.annotation.Reference;
import org.bson.types.ObjectId;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
public class CommentService {


    @Reference
    private CommentApi commentApi;

    @Reference
    private UserInfoApi userInfoApi;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    /**
     * 动态的点赞
     * @param publishId
     * @return
     */
    public int like(String publishId) {
        //1. 构建pojo
        Comment comment = new Comment();
        comment.setTargetType(1);//操作目标类型 1-动态
        comment.setCommentType(1);//操作类型 1-点赞
        comment.setTargetId(new ObjectId(publishId));//操作目标的id 动态的id
        comment.setUserId(UserHolder.getUserId()); // 是谁点的赞,登录用户
        //2. 调用api点赞
        int likeCount = commentApi.save(comment);
        // 点赞时记录redis, 查询时 判断是否点赞过了
        String key = "publish_like_" + UserHolder.getUserId() + "_" + publishId;
        stringRedisTemplate.opsForValue().set(key,"1");
        return likeCount;
    }

    /**
     * 动态的取消点赞
     * @param publishId
     * @return
     */
    public int dislike(String publishId) {
        //1. 构建删除的pojo
        Comment pojo = new Comment();
        //2. 设置删除的条件
        pojo.setUserId(UserHolder.getUserId());
        pojo.setCommentType(1); //1点赞操作
        pojo.setTargetId(new ObjectId(publishId));
        //3. 调用api删除点赞
        int likeCount = commentApi.remove(pojo);
        // 清除redis中的点赞标记
        String key = "publish_like_" + UserHolder.getUserId() + "_" + publishId;
        stringRedisTemplate.delete(key);
        //4. 返回最新的点赞数
        return likeCount;
    }

    /**
     * 动态的喜欢
     * @param publishId
     * @return
     */
    public int love(String publishId) {
        //1. 构建pojo
        Comment comment = new Comment();
        comment.setTargetType(1);//操作目标类型 1-动态
        comment.setCommentType(3);//操作类型 1-喜欢
        comment.setTargetId(new ObjectId(publishId));//操作目标的id 动态的id
        comment.setUserId(UserHolder.getUserId()); // 是谁点的喜欢,登录用户
        //2. 调用api喜欢
        int loveCount = commentApi.save(comment);
        // 喜欢时记录到redis, 查询时 判断是否喜欢过了
        String key = "publish_love_" + UserHolder.getUserId() + "_" + publishId;
        stringRedisTemplate.opsForValue().set(key,"1");
        return loveCount;
    }

    /**
     * 动态的取消喜欢
     * @param publishId
     * @return
     */
    public int unlove(String publishId) {
        //1. 构建删除的pojo
        Comment pojo = new Comment();
        //2. 设置删除的条件
        pojo.setUserId(UserHolder.getUserId());
        pojo.setCommentType(3); //3喜欢操作
        pojo.setTargetId(new ObjectId(publishId));
        //3. 调用api删除喜欢
        int loveCount = commentApi.remove(pojo);
        // 清除redis中的喜欢标记
        String key = "publish_love_" + UserHolder.getUserId() + "_" + publishId;
        stringRedisTemplate.delete(key);
        //4. 返回最新的喜欢数
        return loveCount;
    }

    /**
     * 分页查询某条动态的评论
     * @param publishId
     * @param page
     * @param pageSize
     * @return
     */
    public PageResult findPage(String publishId, Long page, Long pageSize) {
        //1. 调用api分页查询某个动态的评论
        PageResult pageResult = commentApi.findPage(publishId, page, pageSize);
        //2. 查询评论者的信息
        //2.1 取出分页的结果集
        List<Comment> commentList = (List<Comment>) pageResult.getItems();
        //2.2 非空判断
        List<CommentVo> voList = new ArrayList<>();
        if(!CollectionUtils.isEmpty(commentList)) {
            //2.3 取出所的评论者的id
            List<Long> userIds = commentList.stream().map(Comment::getUserId).collect(Collectors.toList());
            //2.4 批量查询评论者信息
            List<UserInfo> userInfoList = userInfoApi.findByBatchId(userIds);
            //2.5 把评论者信息转成map
            Map<Long, UserInfo> userInfoMap = userInfoList.stream().collect(Collectors.toMap(UserInfo::getId, u -> u));
            //3. 转成vo
            //3.1 遍历评论结果集
            for (Comment comment : commentList) {
                //3.2 转成vo
                CommentVo vo = new CommentVo();
                BeanUtils.copyProperties(comment,vo);
                BeanUtils.copyProperties(userInfoMap.get(comment.getUserId()),vo);
                vo.setId(comment.getId().toHexString());
                vo.setCreateDate(RelativeDateFormat.format(new Date(comment.getCreated())));
                //TODO 是否点赞过处理
                String key = "comment_like_" + UserHolder.getUserId() + "_" + vo.getId();
                if (stringRedisTemplate.hasKey(key)) {
                    vo.setHasLiked(1);// 点赞过了
                }
                voList.add(vo);
            }
        }
        //3.3 把voList设置到pageResult
        pageResult.setItems(voList);
        //4. 返回 pageResult
        return pageResult;
    }

    /**
     * 对动态发表评论
     * @param paramMap
     */
    public void add(Map<String, String> paramMap) {
        //1. 构建评论pojo
        Comment pojo = new Comment();
        pojo.setTargetId(new ObjectId(paramMap.get("movementId")));//动态的id
        pojo.setContent(paramMap.get("comment"));// 评论的内容
        pojo.setUserId(UserHolder.getUserId());
        pojo.setTargetType(1);//对动态操作
        pojo.setCommentType(2); // 评论
        //2. 调用api保存
        commentApi.save(pojo);
    }

    /**
     * 对评论的点赞
     * @param commentId
     * @return
     */
    public int likeComment(String commentId) {
        //1. 构建pojo
        Comment comment = new Comment();
        comment.setTargetType(3);//操作目标类型 3-评论
        comment.setCommentType(1);//操作类型 1-点赞
        comment.setTargetId(new ObjectId(commentId));//操作目标的id 评论的id
        comment.setUserId(UserHolder.getUserId()); // 是谁点的赞,登录用户
        //2. 调用api点赞
        int likeCount = commentApi.saveComment(comment);
        // 点赞时记录redis, 查询时 判断是否点赞过了
        String key = "comment_like_" + UserHolder.getUserId() + "_" + commentId;
        stringRedisTemplate.opsForValue().set(key,"1");
        return likeCount;
    }

    /**
     * 对评论的取消点赞
     * @param commentId
     * @return
     */
    public int dislikeComment(String commentId) {
        //1. 构建删除的pojo
        Comment pojo = new Comment();
        //2. 设置删除的条件
        pojo.setUserId(UserHolder.getUserId());
        pojo.setCommentType(1); //1点赞操作
        pojo.setTargetId(new ObjectId(commentId));
        //3. 调用api删除点赞
        int likeCount = commentApi.removeComment(pojo);
        // 清除redis中的点赞标记
        String key = "comment_like_" + UserHolder.getUserId() + "_" + commentId;
        stringRedisTemplate.delete(key);
        //4. 返回最新的点赞数
        return likeCount;
    }
}
